package com.xcity.robot.net.pomelo;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

import com.alibaba.fastjson.JSON;
import com.xcity.robot.App.Config;
import com.xcity.robot.net.Session;
import com.xcity.robot.net.packet.HandshakeAckPacket;
import com.xcity.robot.net.pomelo.impl.HeartbeatWriter;
import com.xcity.robot.net.util.SessionUtils;
import com.xcity.robot.net.websocket.HandshakeListener;

import naga.x.App;
import naga.x.net.Packet;
import naga.x.net.impl.pomelo.body.response.HandshakeResponseBody;
import naga.x.net.impl.pomelo.config.Dictionary;
import naga.x.net.impl.pomelo.protocol.Package;

public class PomeloDecoder extends ProtocolDecoderAdapter {

	static int scheduleId;
	static final ScheduledExecutorService SCHEDULE = Executors.newScheduledThreadPool(6, new ThreadFactory() {
		@Override
		public Thread newThread(Runnable r) {
			Thread t = new Thread(r, "SCHEDULE-" + (++scheduleId));
			t.setDaemon(true);
			return t;
		}
	});
	
	@Override
	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		Package pkg = Package.decode(in);
		switch (pkg.getType()) {
			case Package.TYPE_HANDSHAKE:
				doHandshake(session, pkg);
				break;
			case Package.TYPE_HEARTBEAT:
				doHeartbeat(session, pkg);
				break;
			case Package.TYPE_DATA:
				doData(session, pkg, out);
				break;
		}
	}
	
	void doHandshake(IoSession session, Package pkg) {
		HandshakeResponseBody body = JSON.parseObject(pkg.getBody(), HandshakeResponseBody.class);
		Dictionary dict = new Dictionary(body.getSys().getDict());
//		App.getApp().getConfig().put(Config.POMELO_DICT, dict);
		Config config = App.getApp().getConfig();
		config.dictionary = dict;
		session.write(HandshakeAckPacket.DEFAULT);
		SCHEDULE.scheduleAtFixedRate(new HeartbeatWriter(session), body.getSys().getHeartbeat(), body.getSys().getHeartbeat(), TimeUnit.SECONDS);
		HandshakeListener listener = (HandshakeListener) session.getAttribute(SessionUtils.POMELO_HANDSHAKE_LISTENER);
		listener.handshakeOk((Session) session.getAttribute(SessionUtils.SESSION));
		System.out.println("----handshake ok:" + body.getSys().getDict());
	}
	
	void doHeartbeat(IoSession session, Package pkg) {
		Integer b = (Integer) session.getAttribute(SessionUtils.RECEIVE_HEARTBEAT_NUM);
		if (b == null) {
			b = 0;
//			Session sess = (Session) session.getAttribute(SessionUtils.SESSION);
//			HandshakeListener.POMELO_HANDSHAKE.handshakeOk(sess);
		}
		session.setAttribute(SessionUtils.RECEIVE_HEARTBEAT_NUM, ++b);
	}
	
	void doData(IoSession session, Package pkg, ProtocolDecoderOutput out) {
		Message message = Message.decode(pkg.getBody());
		Packet packet = message.getPacket();
		if (packet != null) {
			out.write(packet);
		}
	}

}
